﻿using DA.AnimGraph;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Unity.Mathematics;
using UnityEngine.UIElements;

namespace DA.AnimGraph.Editor {
    [NodeMenuItem(typeof(AGANode_Revolve), "Revolve")]
    internal class NodeView_Revolve : NodeViewBase {
        public override string titleText => "Revolve";
        protected override NodeViewInspectorSourceBase dataSource => inspectorData;
        NodeViewInspector_Revolve inspectorData;
        internal override void Init(AGAHandle_Node handle, AnimGraphView graphView, AGEEnvironment ageContext) {
            inspectorData = new NodeViewInspector_Revolve();
            inspectorData.SetHandle(handle);
            base.Init(handle, graphView, ageContext);
        }
    }

    internal class NodeViewInspector_Revolve : NodeViewInspectorSourceBase {
        [InspectorField(label: "监听参数")] public AGAFieldModel_IntLink listen;
        [InspectorField(label: "过渡时间")] public RefField<float> defaultTransitionDuration;
        [InspectorField(tag: "inputPort", isList: true)]
        public List<AGAFieldModel_InputPort> inputPort;
        protected override void LoadFromModel() {
            var model = handleKeeper.handle.data.modelProperty as AGANodeModel_Revolve;
            listen = model.listen;
            defaultTransitionDuration = new RefField<float>(model.defaultTransitionDuration);

            // inputPort
            var bNode = handleKeeper.handle.data as AGANode_BlendBase;
            int childrenCount = bNode.inputChildren.Count;
            inputPort = new List<AGAFieldModel_InputPort>(childrenCount);
            for (int i = 0; i < childrenCount; i++) {
                inputPort.Add(new AGAFieldModel_InputPort(bNode.inputNames[i], bNode.inputChildren[i]));
            }
        }
        protected override void SaveToModel() {
            handleKeeper.handle.ModifyModel(m => {
                var model = m as AGANodeModel_Revolve;
                model.defaultTransitionDuration = defaultTransitionDuration.value;
            });

            // 全量覆盖保存输入端口
            var newInputs = inputPort.Select(m => (m.portUuid, m.name)).ToList();
            handleKeeper.handle.WriteAllInput(newInputs);
            
            var listView = inspectorWidgets["inputPort"] as ListViewAGE;
            listView.Rebuild();
        }
        protected override VisualElement CustomizeField(string name, InspectorFieldAttribute fieldAttribute, FieldInfo fieldInfo, AGEContext ageContext, Action inspectorChangeCallback) {
            if (fieldAttribute.tag == "inputPort") {
                return BuildInputPortList(name, fieldAttribute, fieldInfo, ageContext, inspectorChangeCallback);
            }
            return base.CustomizeField(name, fieldAttribute, fieldInfo, ageContext, inspectorChangeCallback);
        }
        VisualElement BuildInputPortList(string name, InspectorFieldAttribute fieldAttribute, FieldInfo fieldInfo, AGEContext ageContext, Action inspectorChangeCallback) {
            var listView = new ListViewAGE() {
                title = name,
                enableCountController = true,
                itemsSource = inputPort,
            };
            listView.makeItem = () => {
                var w = new FoldoutWrapper();
                w.upButtonClicked += (index) => {
                    (inputPort[index], inputPort[index - 1]) = (inputPort[index - 1], inputPort[index]);
                    inspectorChangeCallback?.Invoke();
                };
                w.downButtonClicked += (index) => {
                    (inputPort[index], inputPort[index + 1]) = (inputPort[index + 1], inputPort[index]);
                    inspectorChangeCallback?.Invoke();
                };
                w.deleteButtonClicked += (index) => {
                    inputPort.RemoveAt(index);
                    inspectorChangeCallback?.Invoke();
                };
                var l = new InspectorField_RevolvePort();
                return (l, w);
            };
            listView.bindItem = (element, wrapper, index) => {
                VisualElement nameInputField = null;
                if (element is InspectorField_RevolvePort field) {
                    field.portField.Init(null, inputPort[index], ageContext, inspectorChangeCallback);
                    nameInputField = field.portField;
                }
                if (wrapper is FoldoutWrapper w) {
                    w.index = index;
                    w.text = $"[{index}]";
                    w.enableUp = index > 0;
                    w.enableDown = index < inputPort.Count - 1;
                    w.enableDelete = inputPort.Count > 1;
                    w.SetToTitle(nameInputField);
                }
            };
            listView.addButtonClicked = () => {
                inputPort.Add(new AGAFieldModel_InputPort("new port"));
                inspectorChangeCallback?.Invoke(); // 这里已经执行了 listView.Rebuild()
            };

            return listView;
        }
    }

    class InspectorField_RevolvePort : VisualElement {
        public InspectorField_InputPort portField; // 这部分不再显示在foldout下，而是在标题上，这里只是持有对象而不添加到显示
        
        public InspectorField_RevolvePort() {
            portField = new() {
                name = "name-field",
                style = {
                    flexGrow = 1,
                }
            };
        }
    }
}
